package cn.ztuo.bitrade.controller;

import cn.ztuo.bitrade.constant.BooleanEnum;
import cn.ztuo.bitrade.entity.*;
import cn.ztuo.bitrade.entity.transform.AuthMember;
import cn.ztuo.bitrade.service.*;
import cn.ztuo.bitrade.util.BigDecimalUtils;
import cn.ztuo.bitrade.util.Md5;
import cn.ztuo.bitrade.util.MessageResult;
import cn.ztuo.bitrade.vo.EmptionRecrodVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import static cn.ztuo.bitrade.constant.SysConstant.SESSION_MEMBER;

@RequestMapping("ieo")
@RestController
@Slf4j
public class IeoController {


    @Autowired
    private IeoEmptionService ieoEmptionService;

    @Autowired
    private EmptionRecordService emptionRecordService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private MemberWalletService walletService;

    @Autowired
    private LocaleMessageSourceService msService;
    @Autowired
    private BourseProductManagerService productManagerService;

    private static final int DEFAULT_DIV_SCALE = 4;

    /**
     * 创建募集订单
     * @param authMember
     * @param id
     * @param number
     * @param jyPassword
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "add-ieo", method = RequestMethod.POST)
    public MessageResult add_record(
            @SessionAttribute(SESSION_MEMBER) AuthMember authMember,
            Long id,
            BigDecimal number,
            String jyPassword
    ) throws Exception {
        //判断该产品是否关闭
        BourseProductManager productManager = productManagerService.getByProductCode("0400");
        if(productManager.getStatus()==0){
            return MessageResult.error(500, msService.getMessage("PRODUCT_CLOSE"));
        }
        if (jyPassword == null || jyPassword.equals("")) {
            return MessageResult.error("交易密码不能为空");
        }
        //hasText(jyPassword, msService.getMessage("MISSING_JYPASSWORD"));
        //验证用户信息
        Member member = memberService.findOne(authMember.getId());
        if (member.getTransactionStatus().equals(BooleanEnum.IS_FALSE)) {
            return MessageResult.error("您当前账户已禁用，请联系客服！");
        }
//        if(member.getMemberLevel() == MemberLevelEnum.GENERAL){
//            return MessageResult.error("请先进行实名认证");
//        }
        //验证交易密码
        String mbPassword = member.getJyPassword();
        //Assert.hasText(mbPassword,msService.getMessage("NO_SET_JYPASSWORD"));
        if (mbPassword == null || mbPassword.equals("")) return MessageResult.error(400, "请先设置交易密码");
        //Assert.isTrue(Md5.md5Digest(jyPassword + member.getSalt()).toLowerCase().equals(mbPassword), msService.getMessage("ERROR_JYPASSWORD"));
        if (!Md5.md5Digest(jyPassword + member.getSalt()).toLowerCase().equals(mbPassword))
            return MessageResult.error(400, "交易密码错误");
        IeoEmption ieo = ieoEmptionService.findById(id);
        //验证状态 0=未开启 1=进行中 2=已结束
        if (ieo.getStatus() != 1) {
            return MessageResult.error(400, "申购计划未开启或已结束");
        }
        //如果开启判断时间是否开始
        Date date = new Date();
        Timestamp timestamp = new Timestamp(date.getTime());
        int bigen = timestamp.compareTo(ieo.getStartTime());
        int end = timestamp.compareTo(ieo.getEndTime());
        if (bigen == -1) return MessageResult.error(400, "申购计划时间未开始");
        if (end == 1) return MessageResult.error(400, "申购计划时间已结束");
        //验证剩余数量
        int min = number.compareTo(ieo.getLimitAmount());
        int max = number.compareTo(ieo.getHaveAmount());
        if (min < 0) return MessageResult.error(400, "不满足最小申购数量");
        if (max > 0) return MessageResult.error(400, "超过最大申购数量");
        if (!BigDecimalUtils.compare(ieo.getSurplusAmount(), number)) return MessageResult.error(400, "剩余数量不足");
        //获取支付募集总价
        BigDecimal account = BigDecimalUtils.mulRound(number, ieo.getRatio(), DEFAULT_DIV_SCALE);
        MemberWallet memberWallet = walletService.findByCoinUnitAndMemberId("USDT", authMember.getId());
        if (!BigDecimalUtils.compare(memberWallet.getBalance(), account)) return MessageResult.error(400, "资产余额不足");
        int isSuccess = ieoEmptionService.subAmount(number, ieo, member.getId());
        if (isSuccess > 0) {
            //封装募集记录
            EmptionRecord order = new EmptionRecord();
            order.setUserId(member.getId());
            order.setUserName(member.getUsername());
            order.setUserMobile(member.getMobilePhone());
            order.setIeoName(ieo.getIeoName());
            order.setSaleCoin(ieo.getSaleCoin());
            order.setSaleAmount(ieo.getSaleAmount());
            order.setRaiseCoin(ieo.getRaiseCoin());
            order.setRatio(ieo.getRatio());
            order.setStartTime(ieo.getStartTime());
            order.setEndTime(ieo.getEndTime());
            order.setStatus("0");
            order.setReceiveAmount(number);
            order.setPayAmount(number);
            order.setExpectTime(ieo.getExpectTime());
            order.setCreateTime(timestamp);
            order.setPicView(ieo.getPicView());
            order.setIeoId(ieo.getId());
            EmptionRecord insetRecord = emptionRecordService.save(order);
            if (insetRecord.getId() > 0) {
                return MessageResult.success("申购成功");
            } else {
                return MessageResult.error(400, "申购失败");
            }
        } else {
            return MessageResult.error(400, "申购失败");
        }
    }
    /**
     * 实现根据剩余数量和时间检查计划完成情况
     */
    //    @Scheduled(fixedRate = 10000)
    public void autoDown() {
        log.info("检查申购订单结束计划任务开启");
        Date date =new Date();
        Timestamp timestamp = new Timestamp(date.getTime());
        List<IeoEmption> ieoEmptions = ieoEmptionService.findAlls();
        ieoEmptions.stream().filter(ieoEmption -> {
            //验证状态 0=未开启 1=进行中 2=已结束
            return ieoEmption.getStatus() == 1;
        }).forEach(ieoEmption -> {
            //判断结束结束时间和剩余量
            if(timestamp.compareTo(ieoEmption.getEndTime()) == 1 || ieoEmption.getSurplusAmount().compareTo(BigDecimal.ZERO)==0){
                ieoEmption.setStatus(2);
                ieoEmptionService.save(ieoEmption);
            }
        });
    }
    /**
     * 查询个人IEO订单记录
     * @param authMember
     * @param startTime
     * @param endTime
     * @param saleCoin
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "order-ieo", method = RequestMethod.POST)
    public MessageResult order(
            @SessionAttribute(SESSION_MEMBER) AuthMember authMember,
            @RequestParam(value = "startTime", defaultValue = "") String startTime,
            @RequestParam(value = "endTime", defaultValue = "") String endTime,
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
            String saleCoin) throws Exception {
        EmptionRecrodVO emptionRecrodVO = new EmptionRecrodVO();
        emptionRecrodVO.setUserId(authMember.getId());
        emptionRecrodVO.setPageNum(pageNum);
        emptionRecrodVO.setPageSize(pageSize);
        if (startTime != null && !startTime.equals("") && endTime != null && !endTime.equals("")) {
            SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String startDate = simple.format(new Date(toLong(startTime)));
            String EndDate = simple.format(new Date(toLong(endTime)));
            emptionRecrodVO.setStartTime(startDate);
            emptionRecrodVO.setEndTime(EndDate);
        }
        if (saleCoin != null && !saleCoin.equals("")) emptionRecrodVO.setSaleCoin(saleCoin);
        Page<EmptionRecord> result = emptionRecordService.getByPage(emptionRecrodVO);
        return MessageResult.getSuccessInstance("成功", result);
    }
    /**
     * 格式转换
     * @param obj
     * @return
     */
    private long toLong(String obj) {
        try {
            return Long.parseLong(obj);
        } catch (Exception e) {
        }
        return 0;
    }
}
